package com.punch.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punch.common.dto.system.dict.DictDTO;
import com.punch.common.dto.system.dict.RedisDictDTO;
import com.punch.common.exception.BusinessException;
import com.punch.system.exception.SysExceptionEnum;
import com.punch.system.mapper.SysDictMapper;
import com.punch.system.model.SysDict;
import com.punch.system.model.SysDictKey;
import com.punch.system.service.DictKeyService;
import com.punch.system.service.DictService;
import com.punch.system.util.DictUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * DictServiceImpl-数据字典表 服务实现类
 *
 * @author wujj
 * @version 1.0.0
 * @since 2020/6/3 20:01
 */
@Service
public class DictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements DictService {

    @Autowired
    @Lazy
    private DictKeyService dictKeyService;

    /**
     * 字典key下字典内容与值
     *
     * @param dictKeyId 字典keyId
     * @return List<DictDTO>
     * @author wujj
     * @since 2020/6/4 14:26
     */
    @Override
    public List<DictDTO> listDictByKey(Long dictKeyId) {
        List<DictDTO> retList = new ArrayList<>();
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysDict::getKeyId, dictKeyId);
        List<SysDict> dictList = this.list(queryWrapper);
        dictList.stream().forEach(dataDict -> {
            DictDTO dictForm = new DictDTO();
            BeanUtils.copyProperties(dataDict, dictForm);
            retList.add(dictForm);
        });
        return retList;
    }

    /**
     * 保存数据字典值和内容
     *
     * @param dictKeyId 字典keyId
     * @param dictKey   字典key
     * @param dictList  资源数据字典列表
     * @return 0
     * @author wujj
     * @since 2020/6/4 14:43
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Long saveDict(Long dictKeyId, String dictKey, List<DictDTO> dictList) {
        //删除原来内容
        UpdateWrapper<SysDict> deleteWrapper = new UpdateWrapper<>();
        deleteWrapper.lambda().eq(SysDict::getKeyId, dictKeyId);
        this.remove(deleteWrapper);
        SysDictKey sysDictKeyEX = dictKeyService.getById(dictKeyId);
        //情况数据字典值操作
        if (CollUtil.isEmpty(dictList)) {
            DictUtil.delSysDictList(dictKey);
            SysDictKey sysDictKey = new SysDictKey();
            sysDictKey.setId(dictKeyId);
            sysDictKey.setStatus(2);
            dictKeyService.updateById(sysDictKey);
            return dictKeyId;
        }
        //重复验证
        List repateList = dictList.stream().collect(Collectors.toMap(e -> e.getDictName(), e -> 1, (a, b) -> a + b)) // 获得元素出现频率的 Map，键为元素，值为元素出现的次数
                .entrySet().stream() // Set<Entry>转换为Stream<Entry>
                .filter(entry -> entry.getValue() > 1) // 过滤出元素出现次数大于 1 的 entry
                .map(entry -> entry.getKey()).collect(Collectors.toList()); // 获得 entry 的键（重复元素）对应的 Stream // 转化为 List
        //说明有重复元素
        if (!CollUtil.isEmpty(repateList)) {
            throw new BusinessException(SysExceptionEnum.DICT_NAME_REPEAT);
        }
        List<SysDict> list = new ArrayList<>();
        dictList.stream().forEach(dictForm -> {
            SysDict sysDict = new SysDict();
            BeanUtils.copyProperties(dictForm, sysDict);
            sysDict.setDictKey(dictKey);
            sysDict.setKeyId(dictKeyId);
            list.add(sysDict);
        });
        saveBatch(list);
        //存入redis中
        DictUtil.putSysDict(dictKey);
        //没有值的key状态变成停用状态
        if (sysDictKeyEX.getStatus() == 2) {
            SysDictKey sysDictKey = new SysDictKey();
            sysDictKey.setId(dictKeyId);
            sysDictKey.setStatus(1);
            dictKeyService.updateById(sysDictKey);
        }


        return dictKeyId;
    }

    /**
     * 根据keys查找多个字典列表
     *
     * @param keys 类型列表
     * @return HashMap<String, List < SysDict>>
     * @author wujj
     * @since 2020/6/4 16:16
     */
    @Override
    public HashMap<String, List<RedisDictDTO>> listMultipleDict(String keys) {
        return Arrays.stream(keys.split(",")).collect(Collectors.toMap(key -> key, DictUtil::getSysDictList, (a, b) -> b, HashMap::new));
    }
}
